package services

import (
	"awesome-devops/applications/devops/process"
	"awesome-devops/applications/models"
	"awesome-devops/applications/tools"
	"awesome-devops/boot"
	"errors"
	"fmt"
	"gitee.com/jjawesomejj/awesome-util/event"
	"gitee.com/jjawesomejj/awesome-util/helper/commonhelper"
	"gitee.com/jjawesomejj/awesome-util/helper/timeHelper"
	"gitee.com/jjawesomejj/awesomehttp/system/helper"
	"strconv"
	"time"
)

type DeployService struct {
}

func (service *DeployService) Create(deploy models.Deploy) {

}

func (service *DeployService) Diff(deploy models.Deploy) ([]tools.GitDiff, error) {
	res := make([]tools.GitDiff, 0)
	p := models.Project{}
	err := p.RowByID(deploy.ProjectId, &p)
	if err != nil {
		return res, nil
	}
	command, err := models.GetGitCommand(p)
	if err != nil {
		return nil, err
	}
	diff, err := command.Diff(deploy.LastCommitId, deploy.CommitId)
	if err != nil {
		return nil, err
	}
	return diff, nil
}
func (service *DeployService) CreateDeploy(projectId int, commitId string, deployComment string) interface{} {
	project := models.Project{}
	err := project.RowByID(projectId, &project)
	if err != nil {
		return err
	}
	command, err := models.GetGitCommand(project)
	if err != nil {
		return err
	}
	log, err := command.CommitLog()
	if err != nil {
		return err
	}
	exist := false
	for _, logItem := range log {
		if logItem.CommitId == commitId {
			exist = true
		}
	}
	if !exist {
		return errors.New("提交记录不存在:" + commitId)
	}
	lastCommitId := log[len(log)-1].CommitId
	lastCommit, err := models.GetLastCommit(projectId)
	if err == nil {
		lastCommitId = lastCommit.CommitId
	}
	deploy := models.Deploy{CommitId: commitId, DeployComment: deployComment, ProjectId: projectId, LastCommitId: lastCommitId}
	deploy.StartAt = timeHelper.TimeStringParseTime("1970-01-01 00:00:00")
	deploy.EndAt = timeHelper.TimeStringParseTime("1970-01-01 00:00:00")
	result := boot.GetDbConnection().Create(&deploy)
	if result.Error != nil {
		return result.Error
	}
	data := map[string]interface{}{
		"content": "创建了发布任务",
		"event":   "on_refresh",
	}
	event.Dispatch("onlog", data)
	return deploy.Id
}
func (service *DeployService) CheckLastCommitId(projectId int, commitId string) (string, error) {
	project := models.Project{}
	err := project.RowByID(projectId, &project)
	if err != nil {
		return "", err
	}
	command, err := models.GetGitCommand(project)
	if err != nil {
		return "", err
	}
	log, err := command.CommitLog()
	if err != nil {
		return "", err
	}
	exist := false
	for _, logItem := range log {
		if logItem.CommitId == commitId {
			exist = true
		}
	}
	if !exist {
		return "", errors.New("提交记录不存在:" + commitId)
	}
	lastCommitId := log[len(log)-1].CommitId
	lastCommit, err := models.GetLastCommit(projectId)
	fmt.Println(lastCommit, "lastCommit")
	fmt.Println(err, err)
	if err == nil {
		lastCommitId = lastCommit.CommitId
	}
	return lastCommitId, nil
}

func (service *DeployService) List(keyword string, projectId string, status string, page int, pageSize int) interface{} {
	deploy := models.Deploy{}
	p := models.Project{}
	query := boot.GetDbConnection().Table(deploy.TableName() + " as deploy")
	query = query.Joins("join " + p.TableName() + " as project on deploy.project_id=project.id")
	if projectId != "" {
		query = query.Where("deploy.project_id", projectId)
	}
	if status != "" {
		query = query.Where("deploy.status", status)
	}
	if keyword != "" {
		query = query.Where("deploy.deploy_comment", keyword)
	}
	query = query.Select("project.project_name,deploy.id,deploy.deploy_comment,deploy.create_time,deploy.update_time,deploy.status,deploy.run_time,deploy.start_at,deploy.end_at")
	query = query.Order("deploy.create_time desc")
	pager, err := deploy.Pager(query, page, pageSize, nil)
	if err != nil {
		return err
	}
	return pager
}

func (service *DeployService) Publish(deployId int, startAt float64) interface{} {
	deployLog := models.Deploy{}
	err := deployLog.RowByID(int(deployId), &deployLog)
	if err != nil {
		return nil
	}
	processList := models.FindProcessByProjectId(deployLog.ProjectId)
	var project models.Project
	p := models.Project{}
	err = p.RowByID(deployLog.ProjectId, &project)
	if err != nil {
		return err
	}
	var errRecord error
	deployLog.StartAt = time.Now()
	deployLog.Status = models.DEPLOY_ING
	boot.GetDbConnection().Save(&deployLog)
	data := map[string]interface{}{
		"content": "开始发布",
		"event":   "on_refresh",
	}
	event.Dispatch("onlog", data)
	standardPool := make([]*tools.Standard, 0)
	for _, processItem := range processList {
		processStd := tools.GetTaskStand(strconv.Itoa(int(deployId)), commonhelper.FormatJson("发布配置名【{name}】执行服务器【{server}】", map[string]string{
			"name":   processItem.Name,
			"server": "发布跳板机",
		}), &standardPool)
		processConfig, err := process.GetProcessConfigByProcess(&project, processItem, deployLog, processStd)
		if err != nil {
			errRecord = err
			break
		}
		_, err = processConfig.RunStep(processStd, project, deployLog, &standardPool)
		if err != nil {
			errRecord = err
			break
		}
	}
	if errRecord != nil {
		deployLog.Status = models.DEPLOY_FAIL
	} else {
		deployLog.Status = models.DEPLOY_SUCCESS
	}
	content := make([]string, 0)
	for _, stdItem := range standardPool {
		content = append(content, stdItem.GetOutput())
	}
	deployLog.Log = commonhelper.JsonEncode(content)
	deployLog.RunTime = helper.NowFloat() - startAt
	deployLog.EndAt = time.Now()
	eventData := map[string]interface{}{
		"content": "发布完成",
		"event":   "on_refresh",
	}
	event.Dispatch("onlog", eventData)
	boot.GetDbConnection().Save(&deployLog)
	if errRecord != nil {
		return err
	}
	return ""
}
